<?php

namespace yisyus\supply\api;

use yisyus\supply\exception\RequestException;
use yisyus\supply\utils\AES;
use yisyus\supply\utils\Client;
use yisyus\supply\utils\Enum;
use yisyus\supply\utils\Sign;

class BaseApi
{
    public $app_secret = '';

    public $app_key = '';


    public static function init($app_key, $app_secret)
    {
        $supplyApi = new SupplyApi();
        $supplyApi->app_key = $app_key;
        $supplyApi->app_secret = $app_secret;
        return $supplyApi;
    }

    /**
     * @param $uri
     * @param array $data
     * @param callable|null $back
     * @return mixed|void
     */
    public function httpPost($uri, array $data,callable $back = null)
    {
        $content = Client::getClient(Enum::SUPPLY_URL, $this->setHeaders($data))
            ->post(Enum::URI_PREFIX.$uri, ['encrypt_str' => $this->paramsEncrypt($data)])
            ->body()
            ->content();
        if ($back == null){
            $content = json_decode($content,true);
            if (!$content) throw new RequestException('请求响应失败', 100);
            $code = $content['status'] ?? $content['code'];
            if ($code != 200) throw new \Exception($content['message'],$code);
            return $content['data'];
        }
       $back($content);
    }

    /**
     * 设置头部参数
     * @param array $data
     * @return array
     */
    protected function setHeaders(array $data)
    {
        $timeStamp = $this->getMillisecond();
        $headers = [
            'api-app-id' => $this->app_key,
            'api-time-stamp' => $timeStamp,
            'api-nonce' => md5($this->app_key . $timeStamp),
        ];
        $headers['api-sign'] = Sign::setSign($headers, $this->app_secret, json_encode($data));
        return $headers;
    }

    /**
     * AES加密
     * @param array $data
     * @return string
     */
    protected function paramsEncrypt(array $data)
    {
        return AES::encrypt(json_encode($data), $this->app_key, $this->app_secret);
    }

    /**
     * 获取时间戳到毫秒
     * @return bool|string
     */
    protected function getMillisecond()
    {
        list($msec, $sec) = explode(' ', microtime());
        $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        return rtrim($msectime, '.0');
    }
}